<template>
  <Dialog v-model="dialogVisible" title="用户导入" width="500">
    <el-upload
      ref="uploadRef"
      v-model:file-list="fileList"
      :action="importUrl"
      :headers="uploadHeaders"
      :data="uploadData"
      :auto-upload="false"
      :disabled="formLoading"
      :limit="1"
      :on-exceed="handleUploadExceed"
      :on-error="handleUploadError"
      :on-success="handleUploadSuccess"
      accept=".xls, .xlsx"
      drag
    >
      <Icon icon="ep:upload" />
      <div class="el-upload__text">将文件拖到此处，或 <em>点击上传</em></div>
      <template #tip>
        <div class="el-upload__tip">
          <div>
            <el-checkbox v-model="overwrite">
              <span class="el-upload__tip font-normal">是否更新已经存在的用户数据</span>
            </el-checkbox>
          </div>
          <span>仅允许导入 xls、xlsx 格式文件。</span>
          <el-link
            :underline="false"
            style="font-size: 12px; vertical-align: baseline"
            type="primary"
            @click="downloadTemplate"
          >
            下载模板
          </el-link>
        </div>
      </template>
    </el-upload>
    <template #footer>
      <el-button :disabled="formLoading" type="primary" @click="submitForm">确 定</el-button>
      <el-button @click="dialogVisible = false">取 消</el-button>
    </template>
  </Dialog>
</template>

<script setup lang="ts">
import { pathResolve } from '@/utils'
import { generic_params, generic_headers, response_err_msg } from '@/config/axios'
import * as StaffApi from '@/api/system/staff'
import * as LoginApi from '@/api/base/login'
import download from '@/utils/download'

defineOptions({ name: 'SystemImportForm' })

const message = useMessage() // 消息弹窗

const dialogVisible = ref(false) // 弹窗的是否展示
const formLoading = ref(false) // 表单加载状态
const uploadRef = ref()
const importUrl = pathResolve(
  pathResolve(import.meta.env.VITE_API_BASE_URL, import.meta.env.VITE_API_PREFIX),
  `/system/staff/import?${generic_params}`
)
const uploadHeaders = ref() // 上传请求头
const uploadData = ref({}) // 上传额外请求参数
const fileList = ref([]) // 文件列表
const overwrite = ref(false) // 是否更新存在的员工

const open = async () => {
  dialogVisible.value = true
  resetForm()
}
defineExpose({ open }) // 提供 open 方法，用于打开弹窗

const submitForm = async () => {
  if (!fileList.value?.length) {
    message.error('请上传文件')
    return
  }
  await LoginApi.checkAuth()
  uploadHeaders.value = {
    ...generic_headers()
  }
  uploadData.value = {
    overwrite: overwrite.value
  }
  formLoading.value = true
  uploadRef.value!.submit()
}

const handleUploadExceed = () => {
  message.error('最多只能上传一个文件！')
}

const handleUploadError = () => {
  // http status code error
  message.error('上传失败，请您重新上传！')
  formLoading.value = false
}

const emit = defineEmits(['success']) // 定义success事件，用于操作成功后的回调
const handleUploadSuccess = (resp: any) => {
  // api result code error
  if (!resp.code?.startsWith('2')) {
    message.error(response_err_msg(resp))
    formLoading.value = false
    return
  }
  const data = resp.data
  let text = '新建成功数量：' + data.createLoginNames.length + '；<br/>'
  text += '更新成功数量：' + data.updateLoginNames.length + '；<br/>'
  let failures = Object.keys(data.failureLoginNames || {}).length
  text += '更新失败数量：' + failures + '；<br/>'
  if (failures) {
    // 获取所有键并取前 10 个
    const displayFailures = 10
    const firstLoginNames = Object.keys(data.failureLoginNames).slice(0, displayFailures)
    for (const loginName of firstLoginNames) {
      text += loginName + ': ' + data.failureLoginNames[loginName] + '<br/>'
    }
    if (failures > displayFailures) {
      text += '...更多未列出'
    }
  }
  message.alert(text, undefined, { dangerouslyUseHTMLString: true })
  formLoading.value = false
  dialogVisible.value = false
  emit('success')
}

const downloadTemplate = async () => {
  const data = await StaffApi.getStaffImportTemplate()
  download.excel(data, '用户导入模版.xls')
}

const resetForm = () => {
  formLoading.value = false
  fileList.value = []
  overwrite.value = false
  nextTick(() => {
    uploadRef.value?.clearFiles()
  })
}
</script>

<style scoped lang="scss"></style>
